﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using YFrameWork.RunTime.UI;

namespace YFrameWork.RunTime
{

    public class UIComponent : YFrameWorkComponent
    {
        ResourceComponent m_Resource;
        GameObject m_UIObject;
        public const string CanvasName = "Prefab/Canvas";
        Transform mUIObjectTran => UIObject.GetComponent<Transform>();
        public GameObject UIObject
        {
            get
            {
                if (m_UIObject == null)
                {
                    if (GameObject.Find(CanvasName) == null)
                    {
                        m_UIObject = GameObject.Instantiate(m_Resource.LoadResource<GameObject>(CanvasName),transform);
                        m_UIObject.name = "Canvas";
                    }
                }
                return m_UIObject;
            }
        }
        private readonly Dictionary<UICanvasBase, List<UIFormType>> UICanvasAllConfigDic = new Dictionary<UICanvasBase,List<UIFormType>>();
        private readonly Dictionary<UIFormType, UIConfigItem> UIAllConfigDic = new Dictionary<UIFormType, UIConfigItem>();
        private readonly Dictionary<UIGroupType, UIGroup> UIAllGroupDic = new Dictionary<UIGroupType, UIGroup>();
        private readonly Dictionary<Type, UICanvasBase> UICanvasDic = new Dictionary<Type, UICanvasBase>();
        private readonly Dictionary<UIFormType, UIForm> LoadedUIDic = new Dictionary<UIFormType, UIForm>();

        private void Awake()
        {
            GameEntry.Instance.GetComponent<EventComponent>().Subscribe(ChangeLanguageArgs.EventID, ChangeLanguage);
            
        }

        private void OnDestroy()
        {
            GameEntry.Instance.GetComponent<EventComponent>().Unsubscribe(ChangeLanguageArgs.EventID, ChangeLanguage);

        }

        public override void ToCreate()
        {
            m_Resource = GameEntry.Instance.GetComponent<ResourceComponent>();
        }

        /// <summary>
        /// 获取UI界面
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetUIForm<T>() where T : UIForm
        {
            foreach (var item in LoadedUIDic.Values)
            {
                if (item.GetType() == typeof(T))
                {
                    return item as T;
                }
            }
            return null;
        }

        /// <summary>
        /// 获取UI配置文件类
        /// </summary>
        /// <param name="uIForm"></param>
        /// <returns></returns>
        public UIConfigItem GetUIConfig(UIFormType uIForm)
        {
            if (!HasConfigUIForm(uIForm))
            {
                Log.Debug("获取Ui配置失败，因为配置中不存在这个界面：{0}", uIForm.ToString());
                return null;
            }
            return UIAllConfigDic[uIForm];

        }

        /// <summary>
        /// 获取并添加一个UIcanvas
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetOrAddUICanvas<T>()where T:UICanvasBase
        {
            Type canvasType = typeof(T);
            T canvasComponent;
            if (!UICanvasDic.ContainsKey(canvasType))
            {
                GameObject m_canvasGo = GameObject.Instantiate(m_Resource.LoadResource<GameObject>(CanvasName), transform);
                if(m_canvasGo.GetComponent<UICanvasBase>() != null)
                {
                    Destroy(m_canvasGo.GetComponent<UICanvasBase>());
                }
                canvasComponent = m_canvasGo.AddComponent<T>();
                UICanvasDic.Add(canvasType, canvasComponent);
            }
            canvasComponent = UICanvasDic[canvasType] as T;
            return canvasComponent;
        }



        /// <summary>
        /// 获取UIGroup
        /// </summary>
        /// <param name="uIFormType"></param>
        /// <returns></returns>
        public UIGroup GetUIGroup(UIFormType uIFormType)
        {
            UIGroup uIGroup = null;
            foreach (var item in UIAllGroupDic)
            {
                if (item.Value.AllUIFormDic.ContainsKey(uIFormType))
                {
                    uIGroup = item.Value;
                    break;
                }
            }
            return uIGroup;
        }

        /// <summary>
        /// 获取UICanvasBase
        /// </summary>
        /// <param name="uIFormType"></param>
        /// <returns></returns>
        public UICanvasBase GetUIFormToUICanvas(UIFormType uIFormType)
        {
            UICanvasBase uICanvasBase = null;
            foreach (var item in UICanvasAllConfigDic)
            {
                foreach (var uitypr in item.Value)
                {
                    if (uIFormType == uitypr)
                    {
                        uICanvasBase = item.Key;
                    }
                }
               
            }
            return uICanvasBase;
        }

        /// <summary>
        /// 添加UI界面到canvas
        /// </summary>
        /// <param name="uIFormType"></param>
        /// <param name="uICanvasBase"></param>
        public void AddUIFormToUICanvas(UIFormType uIFormType, UICanvasBase uICanvasBase)
        {
            if (!UICanvasAllConfigDic.ContainsKey(uICanvasBase))
            {
                
                UICanvasAllConfigDic.Add(uICanvasBase, new List<UIFormType>() { uIFormType });
            }
            UICanvasAllConfigDic[uICanvasBase].Add(uIFormType);
        }



        /// <summary>
        /// 配置表添加UI界面
        /// </summary>
        /// <param name="uIConfig"></param>
        public void AddUIForm(UIConfigItem uIConfig)
        {
            if (string.IsNullOrEmpty(uIConfig.m_Path)) Log.Error("UI配置的路径是空的");
            if (uIConfig.m_Type == UIFormType.none) Log.Error("UI配置的面板类型是空的");
            if (uIConfig.m_Group == UIGroupType.none) Log.Error("UI配置的组是空的");

            if (!UIAllConfigDic.ContainsKey(uIConfig.m_Type))
            {
                UIAllConfigDic.Add(uIConfig.m_Type, uIConfig);
            }
        }

        /// <summary>
        /// 添加uiFroup
        /// </summary>
        /// <param name="_uIGroup"></param>
        /// <returns></returns>
        public UIGroup AddUIGroup(UIGroupType _uIGroup)
        {
            return AddUIGroup(_uIGroup, null);
        }

        /// <summary>
        /// 添加UIGroup
        /// </summary>
        /// <param name="_uIGroup"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public UIGroup AddUIGroup(UIGroupType _uIGroup, UIConfigItem config)
        {
            if (!HasUIGroup(_uIGroup))
            {
                UIGroup UpuiGrup = null;
                for (int i = (int)_uIGroup - 1; i >= 0; i--)
                {
                    if (HasUIGroup((UIGroupType)i))
                    {
                        UpuiGrup = UIAllGroupDic[(UIGroupType)i];
                        break;
                    }
                }
                RectTransform tempRoot = new GameObject(_uIGroup.ToString(), typeof(RectTransform)).transform as RectTransform;
                UIGroup uIGroup = tempRoot.gameObject.GetOrAddComponent<UIGroup>();
                UIAllGroupDic.Add(_uIGroup, uIGroup);

                UICanvasBase uiCanvasBase = GetUIFormToUICanvas(config.m_Type);
                if (uiCanvasBase == null)
                {
                    tempRoot.SetParent(mUIObjectTran);
                }
                else
                {
                    tempRoot.SetParent(uiCanvasBase.transform);
                }
                uIGroup.Init(tempRoot);
                if (UpuiGrup != null)
                {
                    tempRoot.SetSiblingIndex(UpuiGrup.CurrentChildCount + 1);
                }
                else
                {
                    tempRoot.SetAsFirstSibling();
                }
            }
            return UIAllGroupDic[_uIGroup];

        }


        /// <summary>
        /// 判断UI配置内是否有ui界面
        /// </summary>
        /// <param name="uIForm"></param>
        /// <returns></returns>
        public bool HasConfigUIForm(UIFormType uIForm)
        {
            if (!UIAllConfigDic.ContainsKey(uIForm))
            {
                Log.Debug("配置中不存在这个ui界面：{0}", uIForm.ToString());
                return false;
            }
            return true;
        }


        /// <summary>
        /// 判断ui界面是否已经加载过
        /// </summary>
        /// <param name="uIForm"></param>
        /// <returns></returns>
        public bool HasLoadedUIForm(UIFormType uIForm)
        {
            if (!LoadedUIDic.ContainsKey(uIForm))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 窗口是否打开
        /// </summary>
        /// <param name="uIFormType"></param>
        /// <returns></returns>
        public bool HasUIFormOpen(UIFormType uIFormType)
        {
            if (LoadedUIDic.TryGetValue(uIFormType,out UIForm uIForm)&& uIForm!=null)
            {
                return uIForm.MOpen;
            }
            return false;
        }

        /// <summary>
        /// 是否存在UIGroup
        /// </summary>
        /// <param name="uIGroupType"></param>
        /// <returns></returns>
        public bool HasUIGroup(UIGroupType uIGroupType)
        {
            return UIAllGroupDic.ContainsKey(uIGroupType);
        }

        /// <summary>
        /// 打开UI界面
        /// </summary>
        /// <param name="uIForm"></param>
        /// <param name="top"></param>
        /// <param name="Obj"></param>
        public void OpenUIForm(UIForm uIForm, bool top = true, object Obj = null)
        {
            UIFormType uIFormType = UIFormType.none;
            foreach (var item in LoadedUIDic)
            {
                if (uIForm == item.Value)
                {
                    uIFormType = item.Key;
                }
            }
            if (uIFormType == UIFormType.none)
            {
                Log.Error("这个ui面板没有加载：{0}", uIForm.GetType().ToString());
                return;
            }
            OpenUIForm(uIFormType, top, Obj);
        }

        /// <summary>
        /// 打开UI界面
        /// </summary>
        /// <param name="uIFormType"></param>
        /// <param name="top"></param>
        /// <param name="Obj"></param>
        public UIForm OpenUIForm(UIFormType uIFormType, bool top = true, object Obj = null)
        {
            return LoadUIForm(uIFormType, top, true, Obj);
        }

        /// <summary>
        /// 关闭UI界面
        /// </summary>
        /// <param name="uIForm"></param>
        /// <param name="Obj"></param>
        public void CloseUIForm(UIForm uIForm, object Obj = null)
        {
            UIFormType uIFormType = UIFormType.none;
            foreach (var item in LoadedUIDic)
            {
                if (uIForm == item.Value)
                {
                    uIFormType = item.Key;
                }
            }
            if (uIFormType == UIFormType.none)
            {
                Log.Error("这个ui面板没有加载：{0}", uIForm.GetType().ToString());
                return;
            }
            CloseUIForm(uIFormType, Obj);
        }

        /// <summary>
        /// 关闭UI界面
        /// </summary>
        /// <param name="uIFormType">ui界面类</param>
        /// <param name="Obj">传递的参数</param>
        public void CloseUIForm(UIFormType uIFormType, object Obj = null)
        {
            if (!LoadedUIDic.ContainsKey(uIFormType))
            {
                //Log.Debug("要关闭的UI界面不存在内存中：{0}", uIFormType.ToString());
                return;
            }

            UIForm uIForm = LoadedUIDic[uIFormType];
            uIForm.Close(Obj);
            uIForm.transform.SetAsFirstSibling();
        }


        /// <summary>
        /// 加载UI界面
        /// </summary>
        /// <param name="uIFormType">界面枚举</param>
        /// <param name="top">是否置顶</param>
        /// <param name="Show">是否显示</param>
        /// <param name="obj">参数</param>
        /// <returns></returns>
        public UIForm LoadUIForm(UIFormType uIFormType,bool top = true, bool Show = false, object obj = null)
        {
            UIConfigItem configItem = GetUIConfig(uIFormType);
            if (configItem == null) return null;
            UIGroup uIGroup = AddUIGroup(configItem.m_Group, configItem);

            UIForm uIForm;
            if (!LoadedUIDic.ContainsKey(uIFormType))
            {
                uIForm = GameObject.Instantiate(m_Resource.LoadResource<GameObject>(configItem.m_Path)).GetOrAddComponent<UIForm>();
                uIForm.transform.name = uIFormType.ToString();
                uIGroup.AddUIForm(uIFormType, uIForm);
                uIForm.Init(obj, Show);
                LoadedUIDic.Add(uIFormType, uIForm);
            }
            else
            {
                uIForm = LoadedUIDic[uIFormType];
            }
            if (Show)
            {
                uIForm.Open(obj);
                if (top) uIForm.transform.SetAsLastSibling();
            }
 
            return uIForm;
        }

        /// <summary>
        /// 移除一个UIForm
        /// </summary>
        /// <param name="uIFormType"></param>
        public void RemoveUIForm(UIFormType uIFormType)
        {
            CloseUIForm(uIFormType);

            UICanvasBase uICanvasBase = null;
            foreach (var item in UICanvasAllConfigDic)
            {
                if (item.Value.Contains(uIFormType))
                {
                    uICanvasBase = item.Key;
                    break;
                }
            }
            if (uICanvasBase != null && UICanvasAllConfigDic[uICanvasBase].Contains(uIFormType))
            {
                UICanvasAllConfigDic[uICanvasBase].Remove(uIFormType);
            }
            UIGroup uIGroup = GetUIGroup(uIFormType);
            if (uIGroup != null)
            {
                uIGroup.RemoveUIForm(uIFormType);
            }

            if (LoadedUIDic.ContainsKey(uIFormType))
            {
                LoadedUIDic.Remove(uIFormType);
            }
        }


        /// <summary>
        /// 延迟显示
        /// </summary>
        /// <param name="go">要延迟的物体</param>
        /// <param name="date">延迟的时间</param>
        public void DelayedShow(GameObject go, float date)
        {
            StartCoroutine(Delayed(go, date));
        }

        /// <summary>
        /// 延迟显示
        /// </summary>
        /// <param name="go">要延迟的物体</param>
        /// <param name="date">延迟的时间</param>
        /// <returns></returns>
        IEnumerator Delayed(GameObject go, float date)
        {
            yield return new WaitForSeconds(date);
            go.SetActive(true);
        }


        /// <summary>
        /// 改变字体事件
        /// </summary>
        /// <param name="ob"></param>
        /// <param name="arges"></param>
        private void ChangeLanguage(object ob,EventArgs arges)
        {
            foreach (var item in LoadedUIDic.Values)
            {
                item.ChangeLanguage();
            }
        }
    }

}